﻿/****************************************************************************
** file: CameraVisionKit.cpp
** brief: 凌云光相机的支持代码
** Copyright (C) LiYuan
** Author: LiYuan
** E-Mail: 18069211#qq(.)com
** Version 0.0.1
** Last modified: 2025.11.17
** Modified By: LiYuan
****************************************************************************/


#include <QDebug>
#include <QDir>
#include <QSettings>
#include <QRegularExpression>
#include "CameraVisionKit.h"

namespace Qly {

bool CameraVisionKit::openCameraByID(QString name)
{

    close();
    m_DeviceVendorName = "Luster";
    m_DeviceModelName = name;
    int a1 = name.indexOf('(');
    int a2 = name.indexOf(')');
    if(a1 == -1 || a2 == -1) // 说明名字里面没有序列号
    {
        m_DeviceSerialNumber = "";
    }
    else
    {
        m_DeviceSerialNumber = name.mid(a1 + 1, a2 - a1 - 1);
    }

    m_hDevHandle = VkGetCameraByName(name.toUtf8().constData());
    if(!m_hDevHandle) {return false;}
    int nRet = VkConnectCamera(m_hDevHandle, CameraVisionKit::DisconnectCallBack, this);
    if (OK != nRet)
    {
        qDebug() << "error: VkConnectCamera fail";
        return false;
    }
    nRet = VkMemoryPoolInit(m_hDevHandle, 3, BLOCK_MEMORY_POOL);
    if (OK != nRet)
    {
        qDebug() << "error: VkMemoryPoolInit fail";
        return false;
    }

    nRet = VkSetGrabMode(m_hDevHandle, GRAB_MODE_CALLBACK );



    dynamic_cast<VisionKitCameraImageProcessing *>(m_cameraImageProcessing)->setDevHandle(m_hDevHandle);
    registerExceptionCallBack();
    return registerImageCallBack();
}

CameraVisionKit::CameraVisionKit(QObject *parent)
    :IndustryCamera(parent),
      m_hDevHandle(nullptr)
{
    //connect(&dia, SIGNAL(exposureTimeAbsChanged(double)), this, SLOT(setExpoureTime(double)));
    //connect(&dia, SIGNAL(gammaChanged(double)), this, SLOT(setGamma(double)));
    //connect(&dia, SIGNAL(autoWhiteBalanceChanged(int)), this, SLOT(autoWhiteBalance(int)));
    m_DeviceVendorName = "Luster";
    m_dialog = new DialogCameraSetup(this);
    //m_cameraImageProcessing = new HikVisionCameraImageProcessing;

    mutex = new QMutex();

//    m_dia->show();
}

///TODO: 这个函数需要重写
bool CameraVisionKit::isLive()
{
    if(m_hDevHandle == nullptr)
    {
        return false;
    }
    //获取设备采集模式
    int nRet = VkIsGrabbing(m_hDevHandle);
    return (OK == nRet);
}
CameraVisionKit::~CameraVisionKit()
{
    close();

    delete m_dialog;
}


QString CameraVisionKit::cameraName()
{
    if( m_hDevHandle == nullptr ) return QString();
    return m_DeviceVendorName + " " +  m_DeviceModelName;
}

void CameraVisionKit::initName()
{
    if( m_hDevHandle == nullptr ) return;
    m_DeviceVendorName = "Luster";
    m_DeviceModelName = "";
    m_DeviceSerialNumber = "";
    m_DeviceID = "";

}

bool CameraVisionKit::openDefaultCamera()
{
    int cameraNum = VkEnumCameraByType(DeviceTypeAll);
    if(cameraNum == 0) return false;

    char cameraName[128];
    int len = VkGetCameraNameByIndex(0, cameraName, 128);
    if(len < 0) return false;
    QString strName(cameraName);
    return openCameraByID(strName);
}

bool CameraVisionKit::setPixelType(AVPixelFormat type)
{
    if (nullptr == m_hDevHandle)
    {
        return false;
    }

    return false;
}

void CameraVisionKit::close()
{
    if (NULL == m_hDevHandle)
    {
 //       qDebug() << "error: Close Device fail";
        return;
    }
    stopGrabbing();
    VkDisconnectCamera(m_hDevHandle);
    VkStopMsgMonitor(m_hDevHandle);
    VkCameraRelease(m_hDevHandle);
    m_hDevHandle = 0;
}


bool CameraVisionKit::saveSettingsToFile(QString fileName)
{
    return false;
}

bool CameraVisionKit::loadSettingsFromFile(QString fileName)
{
    return false;
}

bool CameraVisionKit::startGrabbing()
{
    m_imageCount = 0;
    if (NULL == m_hDevHandle)
    {
        qDebug() << "error: OpenDevice fail";
        return false;
    }
    int nRet = VkStartGrab (m_hDevHandle, 10000, 0, this);
    if (OK != nRet)
    {
        qDebug() << "error: VkStartGrab fail";
        return false;
    }
    return true;
}

bool CameraVisionKit::stopGrabbing()
{
    if (NULL == m_hDevHandle)
    {
        return false;
    }
    int nRet = VkStopGrab (m_hDevHandle, 0);
    if (OK != nRet)
    {
        qDebug() << "error: VkStopGrab fail";
        return false;
    }
    return true;
}

bool CameraVisionKit::registerExceptionCallBack()
{
    if (NULL == m_hDevHandle)
    {
         return false;
    }

    int nRet = VkStartMsgMonitor (m_hDevHandle, MsgCallbackFunc, this);
    if (OK != nRet)
    {
        qWarning() << "error: VkStartMsgMonitor() fail";
        return false;
    }
    qInfo() << "VkStartMsgMonitor() Success!";

    return true;
}

void CameraVisionKit::ImageCallBack(IMAGE image, void *pUser)
{

    CameraVisionKit *camera = static_cast<CameraVisionKit *> (pUser);
    IMAGE_INFO info;
    VkGetImageInfo(image, &info);
    unsigned char * pData = VkGetImageBuff(image);

    QSize size(info.width, info.height);
    camera->m_imageCount++;

    AVPixelFormat format = AV_PIX_FMT_NONE;
    int stride = info.width;
    switch(info.format)
    {
    case PIXEL_FORMAT_MONO8 :
        format = AV_PIX_FMT_GRAY8;
        stride = info.width;
        break;
    case PIXEL_FORMAT_MONO10 :
        format = AV_PIX_FMT_GRAY8;
        stride = info.width * 2;
        break;
    case PIXEL_FORMAT_MONO12  :
        format = AV_PIX_FMT_GRAY8;
        stride = info.width * 2;
        break;
    case PIXEL_FORMAT_MONO14 :
        format = AV_PIX_FMT_GRAY8;
        stride = info.width * 2;
        break;
    case PIXEL_FORMAT_MONO16 :
        format = AV_PIX_FMT_GRAY8;
        stride = info.width * 2;
        break;

    case PIXEL_FORMAT_RGB8:
        format = AV_PIX_FMT_RGB24;
        stride = info.width * 3;
        break;

    case PIXEL_FORMAT_BGR8:
        format = AV_PIX_FMT_BGR24;
        stride = info.width * 3;
        break;

    case PIXEL_FORMAT_BAYER_GB8:
        format = AV_PIX_FMT_BAYER_GBRG8;
        stride = info.width;
        break;
    case PIXEL_FORMAT_BAYER_GR8 :
        format = AV_PIX_FMT_BAYER_GRBG8;
        stride = info.width;
        break;
    case PIXEL_FORMAT_BAYER_RG8 :
        format = AV_PIX_FMT_BAYER_RGGB8;
        stride = info.width;
        break;
    case PIXEL_FORMAT_BAYER_BG8  :
        format = AV_PIX_FMT_BAYER_BGGR8;
        stride = info.width;
        break;
    case PIXEL_FORMAT_RGBa8  :
        format = AV_PIX_FMT_RGB32;
        stride = info.width * 4;
        break;
    }

    VideoFrame frame(pData, stride, size, format);//, camera->mutex);
    frame.setExtraInfo(camera->m_imageCount++, QDateTime::currentDateTime());
    //camera->mutex->lock();
    emit camera->videoFrameReady(frame);

    VkImageRelease(image);
}

void CameraVisionKit::MsgCallbackFunc(const EVENT_ITEM *eventItem, const unsigned char *data, unsigned int dataSize, void *context)
{

}

bool CameraVisionKit::registerImageCallBack()
{
    if (NULL == m_hDevHandle)
    {
         return false;
    }
    int nRet = VkRegisterCallBack(m_hDevHandle, 0, ImageCallBack);
    if (OK  != nRet)
    {
        qWarning() << "error: VkRegisterCallBack() fail";
        return false;
    }
    qInfo() << "VkRegisterCallBack() Success!";
    return true;
}

bool CameraVisionKit::setExposureTimeMode(AutoExposureMode mode)
{
    if (NULL == m_hDevHandle)
    {
         return false;
    }
    int nRet;
    switch (mode) {
    case IndustryCamera::OFF:
        //nRet = MV_CC_SetExposureAutoMode(m_hDevHandle, MV_EXPOSURE_AUTO_MODE_OFF);
        break;
    case IndustryCamera::CONTINUOUS:
        ///nRet = MV_CC_SetExposureAutoMode(m_hDevHandle, MV_EXPOSURE_AUTO_MODE_CONTINUOUS);
        break;
    case IndustryCamera::ONCE:
        //nRet = MV_CC_SetExposureAutoMode(m_hDevHandle, MV_EXPOSURE_AUTO_MODE_ONCE);
        break;
    }
    if (OK != nRet)
    {
        qDebug() << "error: SetExposureAutoMode MV_EXPOSURE_AUTO_MODE_ONCE fail";
        return false;
    }
    return true;
}

bool CameraVisionKit::exposureTimeMode(AutoExposureMode &mode)
{
    if (NULL == m_hDevHandle)
    {
         return false;
    }
    int nRet;

    return false;
}
//bool CameraVisionKit::setExpoureTimeOnePush()
//{
//    if (NULL == m_hDevHandle)
//    {
//         return false;
//    }
//    int nRet = MV_CC_SetExposureAutoMode(m_hDevHandle, MV_EXPOSURE_AUTO_MODE_ONCE);
//    if (MV_OK != nRet)
//    {
//        qDebug() << "error: SetExposureAutoMode MV_EXPOSURE_AUTO_MODE_ONCE fail";
//        return false;
//    }
//    return true;
//}


bool CameraVisionKit::showVCDPropertyPage()
{
    m_dialog->initNodeInfo();
    m_dialog->show();
    return false;
}

bool CameraVisionKit::setHeartBeatTimeout(int ms)
{
    if (NULL == m_hDevHandle)
    {
         return false;
    }

    return false;
}

bool CameraVisionKit::setAOIRegion(QRect rect)
{
    if (NULL == m_hDevHandle)
    {
         return false;
    }
    return false;

}

bool CameraVisionKit::frameRate(double &fps)
{
    fps = 0;
    if (NULL == m_hDevHandle)
    {
         return false;
    }
    //获取相机采集帧率信息
    return false;
}

bool CameraVisionKit::setFrameRate(double fps)
{
    if (NULL == m_hDevHandle)
    {
         return false;
    }
    //设置相机采集帧率

    return false;
}

bool CameraVisionKit::autoExposure(bool &on)
{
    if(m_hDevHandle == nullptr)
    {
        return false;
    }

    return false;
}

bool CameraVisionKit::autoExposureTimeLowerLimitRange(int &nMin, int &nMax, int &nValue)
{
    if (NULL == m_hDevHandle)
    {
         return false;
    }
    //Get int parameter

    return false;
}

bool CameraVisionKit::autoExposureTimeUpperLimitRange(int &nMin, int &nMax, int &nValue)
{
    if (NULL == m_hDevHandle)
    {
         return false;
    }
    //Get int parameter
    return false;
}

bool CameraVisionKit::exposureTimeRange(double &min, double &max, double &fValue)
{
    if (NULL == m_hDevHandle)
    {
         return false;
    }
    //获取相机曝光值
    return false;
}

bool CameraVisionKit::imageSize(QSize &size, QSize &max, QSize &min)
{
    if (NULL == m_hDevHandle)
    {
         return false;
    }
    return false;
}

bool CameraVisionKit::exposureTime(double &us)
{
    //获取相机曝光值

    return false;
}

bool CameraVisionKit::setExposureTime(double us)
{
    //获取相机曝光值

    return false;
}

void CameraVisionKit::DisconnectCallBack(unsigned int x, void *p)
{
    CameraVisionKit * pCamera = (CameraVisionKit * )p;
    qDebug() << "Camera disconnected";
    emit pCamera->deviceLost();
}

} //namespace Qly

